home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / dc1 / types.c < prev    next >
C/C++ Source or Header  |  1997-09-09  |  19KB  |  796 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6. /*
  7.  *  TYPES.C
  8.  */
  9.  
  10. /*
  11. **      $Filename: types.c $
  12. **      $Author: dice $
  13. **      $Revision: 30.325 $
  14. **      $Date: 1995/12/24 05:38:17 $
  15. **      $Log: types.c,v $
  16.  * Revision 30.325  1995/12/24  05:38:17  dice
  17.  * .
  18.  *
  19.  * Revision 30.5  1994/06/13  18:37:41  dice
  20.  * .
  21.  *
  22.  * Revision 30.0  1994/06/10  18:04:58  dice
  23.  * .
  24.  *
  25.  * Revision 1.11  1994/04/15  21:19:38  jtoebes
  26.  * Fix error message for undefined tag to correspond to the error message file.
  27.  *
  28.  * Revision 1.10  1993/11/22  00:28:36  jtoebes
  29.  * Final cleanup to eliminate all cerror() messages with strings.
  30.  *
  31.  * Revision 1.9  1993/11/14  21:38:47  jtoebes
  32.  * FIXED BUG01140 - DC1 is misaligning structure sizes.
  33.  * Set the alignment size of the char array.
  34.  *
  35.  * Revision 1.8  1993/11/14  18:26:01  jtoebes
  36.  * Fixed BUG00059 - Long Double constants not supported.
  37.  * Slight kludge by setting the size to 8 so that it acts just like
  38.  * a normal double.
  39.  *
  40.  * Revision 1.7  1993/11/14  17:20:35  jtoebes
  41.  * Fix overzealous error messages for pointer mismatches.
  42.  *
  43.  * Revision 1.6  1993/10/17  11:02:49  jtoebes
  44.  * FIXED BUG01133 - Strange warning about mismatch of return type for the assignment
  45.  * of a function pointer.  This change now causes the compiler to tell you the type
  46.  * that it was comparing with as well as the expected type.  This should help a lot
  47.  * of people in figuring out what the error was.
  48.  *
  49.  * Revision 1.5  1993/09/06  21:39:04  jtoebes
  50.  * Fix BUG01005 - Problems with typedef of a tentative volatile structure.
  51.  * I am not 100% comfortable with this fix, but it does address the basic issue.
  52.  *
  53. **/
  54.  
  55. #include "defs.h"
  56.  
  57. Prototype long NumTypesAlloc;
  58.  
  59. Prototype Type VoidType;
  60. Prototype Type CharType;
  61. Prototype Type ShortType;
  62. Prototype Type LongType;
  63. Prototype Type CharPtrType;
  64. Prototype Type CharAryType;
  65. Prototype Type VoidPtrType;
  66. Prototype Type LongPtrType;
  67.  
  68. Prototype Type UCharType;
  69. Prototype Type UShortType;
  70. Prototype Type ULongType;
  71.  
  72. Prototype Type FloatType;
  73. Prototype Type DoubleType;
  74. Prototype Type LongDoubleType;
  75.  
  76. Prototype Type DefaultProcType;
  77.  
  78.  
  79. long NumTypesAlloc;
  80.  
  81. typedef struct SUSym {
  82.     struct SUSym *Next;
  83.     struct Symbol *Sym;
  84.     struct Type *Type;
  85. } SUSym;
  86.  
  87. #define HSIZE    256
  88. #define HMASK    (HSIZE-1)
  89.  
  90. Type VoidType        = { TID_INT,    1, 0,        0    };
  91. Type CharType        = { TID_INT,    1, 0,        1    };
  92. Type ShortType        = { TID_INT,    2, 0,        2    };
  93. Type LongType        = { TID_INT,    2, 0,        4    };
  94. Type CharPtrType    = { TID_PTR,    2, TF_UNSIGNED, 4    };
  95. Type CharAryType    = { TID_ARY,    1, TF_UNSIGNED, 4    };
  96. Type VoidPtrType    = { TID_PTR,    2, TF_UNSIGNED, 4    };
  97. Type LongPtrType    = { TID_PTR,    2, TF_UNSIGNED, 4    };
  98.  
  99. Type UCharType        = { TID_INT,    1, TF_UNSIGNED, 1    };
  100. Type UShortType     = { TID_INT,    2, TF_UNSIGNED, 2    };
  101. Type ULongType        = { TID_INT,    2, TF_UNSIGNED, 4    };
  102.  
  103. Type FloatType        = { TID_FLT,    2, 0,        4    };
  104. Type DoubleType     = { TID_FLT,    2, 0,        8    };
  105. Type LongDoubleType = { TID_FLT,    2, 0,        8    };  /* Should be 16 */
  106.                      /* By leaving long double at 8 for now, it acts like double */
  107.  
  108. Type DefaultProcType= { TID_PROC,   4, 0,        4    };
  109.  
  110. static Type *SBitfieldType[32];
  111. static Type *UBitfieldType[32];
  112.  
  113. static SUSym *SUHash[HSIZE];
  114.  
  115. Prototype void InitTypes(int);
  116. Prototype void LooseTypeLink(Type *, Type *);
  117. Prototype void TypeLink(Type *, Type *);
  118. Prototype void TypeLinkEnd(Type *, Type *);
  119. Prototype Type *TypeToPtrType(Type *);
  120. Prototype Type *TypeToAryType(Type *, Exp *, long);
  121. Prototype Type *TypeToProcType(Type *, Var **, short, long);
  122. Prototype Type *TypeToQualdType(Type *, long);
  123. Prototype Type *FindStructUnionType(Symbol *, long);
  124. Prototype Symbol *FindStructUnionTag(Type *);
  125. Prototype long FindStructUnionElm(Type *, Exp *, int *);
  126. Prototype Type *MakeStructUnionType(Symbol *, long);
  127. Prototype void SetStructUnionType(Type *, Var **, long, long);
  128. Prototype Type *MakeBitfieldType(long, int);
  129. Prototype Type *FindEnumType(Symbol *);
  130. Prototype Type *MakeEnumType(Symbol *);
  131. Prototype void AddEnumIdent(Type *, Symbol *, long);
  132. Prototype Type *ActualReturnType(Stmt *, Type *, Type *);
  133. Prototype Type *ActualPassType(Type *, Type *, int);
  134. Prototype Type *ActualArgType(Type *);
  135. Prototype void CheckPointerType(long, long, Type *, Type *);
  136. Prototype void GenerateRegSpecOutput(Var *);
  137. Prototype void Undefined_Tag(Type *, Symbol *, long);
  138.  
  139. void
  140. InitTypes(int enab)
  141. {
  142.     static short Refs;
  143.  
  144.     DefaultProcType.Args = -1;
  145.     if (enab == 1 && Refs++ == 0) {
  146.     TypeLink(&CharType, &CharPtrType);
  147.     TypeLink(&CharType, &CharAryType);
  148.     TypeLink(&VoidType, &VoidPtrType);
  149.     TypeLink(&LongType, &LongPtrType);
  150.     TypeLink(&LongType, &DefaultProcType);
  151.     LooseTypeLink(&CharType,  &UCharType);
  152.     LooseTypeLink(&ShortType, &UShortType);
  153.     LooseTypeLink(&LongType,  &ULongType);
  154.     }
  155.     if (enab == 0 && --Refs == 0) {
  156.     ;
  157.     }
  158. }
  159.  
  160. void
  161. LooseTypeLink(roottype, qualtype)
  162. Type *qualtype;
  163. Type *roottype;
  164. {
  165.     qualtype->Next = roottype->PList;
  166.     roottype->PList = qualtype;
  167. }
  168.  
  169. void
  170. TypeLink(subtype, partype)
  171. Type *subtype;
  172. Type *partype;
  173. {
  174.     partype->SubType = subtype;
  175.     partype->Next = subtype->PList;
  176.     subtype->PList = partype;
  177. }
  178.  
  179. void
  180. TypeLinkEnd(subtype, partype)
  181. Type *subtype;
  182. Type *partype;
  183. {
  184.     Type **pt;
  185.  
  186.     for (pt = &subtype->PList; *pt; pt = &(*pt)->Next);
  187.  
  188.     partype->SubType = subtype;
  189.     partype->Next = *pt;
  190.     *pt = partype;
  191. }
  192.  
  193.  
  194. /*
  195.  *  Note that we must also compare SubType to type because there are
  196.  *  relationships other than parent-child stored here (TypeToQualdType)
  197.  */
  198.  
  199. Type *
  200. TypeToPtrType(type)
  201. Type *type;
  202. {
  203.     Type *t;
  204.  
  205.     for (t = type->PList; t; t = t->Next) {
  206.     if (t->Id == TID_PTR && t->SubType == type)
  207.         return(t);
  208.     }
  209.     ++NumTypesAlloc;
  210.     t = AllocStructure(Type);
  211.     t->Id = TID_PTR;
  212.     t->Align = 2;
  213.     t->Size = 4;
  214.     TypeLink(type, t);
  215.     return(t);
  216. }
  217.  
  218. Type *
  219. TypeToAryType(type, exp, entries)
  220. Type *type;
  221. Exp *exp;
  222. long entries;
  223. {
  224.     long size;
  225.     Type *t;
  226.  
  227.     if (exp)
  228.     entries = ExpToConstant(exp);
  229.     size = entries * type->Size;
  230.     if (entries) {
  231.     for (t = type->PList; t; t = t->Next) {
  232.         if (t->Id == TID_ARY && size == t->Size && t->SubType == type)
  233.         return(t);
  234.     }
  235.     }
  236.     ++NumTypesAlloc;
  237.     t = AllocStructure(Type);
  238.     t->Id = TID_ARY;
  239.     t->Align = type->Align;
  240.     t->Size = size;
  241.     if (type->Flags & TF_CONST)     /*    array of const is const array    */
  242.     t->Flags |= TF_CONST;
  243.     TypeLink(type, t);
  244.     return(t);
  245. }
  246.  
  247. /*
  248.  *  Create a procedural type.
  249.  *
  250.  *  Here we try to optimize storage by searching if the procedural type is
  251.  *  already declared.  If the 'vars' arg has symbols, however, we can't do
  252.  *  that because the procedure generation needs to know the variable names.
  253.  *
  254.  *  if 'vars' has no symbols then we don't care if we optimize by giving it
  255.  *  some, because they will never be used.  However, if vars does have
  256.  *  symbols than the type list might be munged due to prototyping (as well
  257.  *  as needing to preserve said symbols), so we make a copy.
  258.  */
  259.  
  260. Type *
  261. TypeToProcType(Type *type, Var **vars, short n, long flags)
  262. {
  263.     Type *t;
  264.  
  265.     for (t = type->PList; t; t = t->Next) {
  266.     if (t->Id == TID_PROC && t->SubType == type) {
  267.         if (t->Args == n && (t->Flags & -1) == (flags & -1)) {  /* XXX */
  268.         short i;
  269.         for (i = 0; i < n; ++i) {
  270.             Var *v1 = vars[i];
  271.             Var *v2 = t->Vars[i];
  272.  
  273.             if (v1->Type != v2->Type || v1->u.Block != v2->u.Block || v1->Sym)
  274.             break;
  275.             if ((v1->RegFlags ^ v2->RegFlags) & (RF_REGISTER|RF_REGMASK))
  276.             break;
  277.         }
  278.         if (n < 0 || i == n)
  279.             return(t);
  280.         }
  281.     }
  282.     }
  283.     {
  284.     short i;
  285.     Var **tvars = NULL;
  286.     Var *xvars = NULL;
  287.  
  288.     if (n > 0) {
  289.         tvars = zalloc(sizeof(Var *) * n);
  290.         xvars = zalloc(sizeof(Var) * n);
  291.     }
  292.     for (i = 0; i < n; ++i) {
  293.         *xvars = *vars[i];
  294.         tvars[i] = xvars++;
  295.     }
  296.     ++NumTypesAlloc;
  297.     t = AllocStructure(Type);
  298.     t->Id = TID_PROC;
  299.     t->Align = 4;
  300.     t->Size = 4;    /* non-zero so asm_getind() does not complain */
  301.     t->Vars = tvars;
  302.     t->Args = n;
  303.     t->Flags= flags;
  304.     TypeLinkEnd(type, t);
  305.     }
  306.     return(t);
  307. }
  308.  
  309. /*
  310.  *  Qualified types are exactly their unqualified brothers
  311.  *  except the Flags and PList fields are different
  312.  */
  313.  
  314. Type *
  315. TypeToQualdType(type, flags)
  316. Type *type;
  317. long  flags;
  318. {
  319.     Type *t;
  320.  
  321.     for (t = type->PList; t; t = t->Next) {
  322.     if (t->Align == type->Align && t->Flags == flags && t->Size == type->Size &&
  323.         t->Id == type->Id && t->SubType == type->SubType && t->Args == type->Args &&
  324.         t->Vars == type->Vars
  325.     ) {
  326.         return(t);
  327.     }
  328.     }
  329.  
  330.     /*
  331.      *    note that SubType is not altered.. what if the type is a pointer or
  332.      *    something!
  333.      */
  334.  
  335.     ++NumTypesAlloc;
  336.     t = AllocStructure(Type);
  337.     *t = *type;
  338.     t->Flags = flags;
  339.     t->Next = type->PList;
  340.     t->PList = NULL;
  341.     type->PList = t;
  342.     return(t);
  343. }
  344.  
  345. /*
  346.  *  STRUCTURES AND UNIONS
  347.  */
  348.  
  349.  
  350. Type *
  351. FindStructUnionType(Symbol *sym, long isUnion)
  352. {
  353.     SUSym *su = SUHash[sym->Hv & HMASK];
  354.  
  355.     while (su && su->Sym != sym)
  356.     su = su->Next;
  357.     if (su) {
  358.     return(su->Type);
  359.     }
  360.     return(NULL);
  361. }
  362.  
  363. Symbol *
  364. FindStructUnionTag(type)
  365. Type *type;
  366. {
  367.     SUSym *su;
  368.     short i;
  369.  
  370.  
  371.     for (i = 0; i < HSIZE; ++i) {
  372.     for (su = SUHash[i]; su; su = su->Next) {
  373.         if (su->Type == type)
  374.         return(su->Sym);
  375.     }
  376.     }
  377.     return(NULL);
  378. }
  379.  
  380. long
  381. FindStructUnionElm(type, exp, pbfo)
  382. Type *type;
  383. Exp *exp;
  384. int *pbfo;
  385. {
  386.     short i;
  387.  
  388.     exp->ex_Type = NULL;
  389.     if (type->Id == TID_PTR)
  390.     type = type->SubType;
  391.  
  392.     if (type->Id != TID_STRUCT && type->Id != TID_UNION) {
  393.     yerror(exp->ex_LexIdx, EERROR_NOT_STRUCT_UNION);
  394.     return(0);
  395.     }
  396.     for (i = 0; i < type->Args; ++i) {
  397.     Var *var = type->Vars[i];
  398.     if (var->Sym == exp->ex_Symbol) {
  399.         exp->ex_Type = var->Type;
  400.         *pbfo = var->u.BOffset;
  401.         return(var->var_Stor.st_Offset);
  402.     }
  403.     }
  404.     yerror(exp->ex_LexIdx, EERROR_UNDEFINED_ELEMENT, SymToString(exp->ex_Symbol));
  405.     return(0);
  406. }
  407.  
  408. /*
  409.  *  sym can be NULL!
  410.  *
  411.  */
  412.  
  413. Type *
  414. MakeStructUnionType(sym, isUnion)
  415. Symbol *sym;
  416. long isUnion;
  417. {
  418.     SUSym **psu = &SUHash[(sym) ? (sym->Hv & HMASK) : 0];
  419.     SUSym *su = AllocStructure(SUSym);
  420.     Type *t = AllocStructure(Type);
  421.  
  422.     ++NumTypesAlloc;
  423.     t->Id = (isUnion) ? TID_UNION : TID_STRUCT;
  424.  
  425.     su->Next = *psu;
  426.     su->Sym  = sym;
  427.     su->Type = t;
  428.     *psu = su;
  429.  
  430.     return(t);
  431. }
  432.  
  433. void
  434. SetStructUnionType(t, vars, nv, flags)
  435. Type *t;
  436. Var **vars;
  437. long nv;
  438. long flags;
  439. {
  440.     long size;
  441.     short boffset;
  442.     short align;
  443.     short i;
  444.     Type *type;
  445.  
  446.     t->Vars = vars;
  447.     t->Args = nv;
  448.  
  449.     align = STRUCT_ALIGN;
  450.     size = 0;
  451.     boffset = INT_SIZE * 8;
  452.     if (flags & TF_UNALIGNED)
  453.     align = 1;
  454.  
  455.     for (i = 0; i < nv; ++i) {
  456.     Var *var = vars[i];
  457.     type = var->Type;
  458.  
  459.     if (var->Flags & TF_ALIGNED) {
  460.         size = Align(size, 4);
  461.         boffset = INT_SIZE * 8; /* XXX */
  462.     }
  463.     if ((type->Id == TID_STRUCT || type->Id == TID_UNION) && type->Size == 0)
  464.     {
  465.         Undefined_Tag(type, NULL, LFBase ? LFBase->lf_Index: 0);
  466.     }
  467.  
  468.     if (align < type->Align && !(flags & TF_UNALIGNED))
  469.         align = type->Align;
  470.     if (t->Id == TID_STRUCT) {
  471.         if (type->Id == TID_BITFIELD) {
  472.         /*
  473.          *  alignment if bitfield does not fit or : 0 field.
  474.          */
  475.         if (type->Size > boffset || type->Size == 0) {
  476.             if (boffset >= BITFIELD_ALIGN * 8) {
  477.             size += BITFIELD_ALIGN;
  478.             boffset = INT_SIZE * 8;
  479.             } else {
  480.             size += INT_SIZE;
  481.             boffset = INT_SIZE * 8;
  482.             }
  483.         }
  484.         size = Align(size, type->Align);
  485.         boffset -= type->Size;
  486.         var->u.BOffset = boffset;
  487.         var->var_Stor.st_Offset = size;
  488.         } else {
  489.         if (boffset != INT_SIZE * 8) {
  490.             if (boffset >= BITFIELD_ALIGN * 8) {
  491.             size += BITFIELD_ALIGN;
  492.             boffset = INT_SIZE * 8;
  493.             } else {
  494.             size += INT_SIZE;
  495.             boffset = INT_SIZE * 8;
  496.             }
  497.         }
  498.         if (!(flags & TF_UNALIGNED))
  499.             size = Align(size, type->Align);
  500.         var->var_Stor.st_Offset = size;
  501.         size += type->Size;
  502.         }
  503.     } else {
  504.         if (type->Id == TID_BITFIELD) {
  505.         var->u.BOffset = 0;
  506.         if (boffset > INT_SIZE * 8 - type->Size)
  507.             boffset = INT_SIZE * 8 - type->Size;
  508.         } else {
  509.         if (size < type->Size)
  510.             size = type->Size;
  511.         }
  512.     }
  513.     }
  514.     if (boffset != INT_SIZE * 8) {    /*  finish up bitfield  */
  515.     if (t->Id == TID_STRUCT) {
  516.         if (boffset >= BITFIELD_ALIGN * 8)
  517.         size += BITFIELD_ALIGN;
  518.         else
  519.         size += INT_SIZE;
  520.     } else {
  521.         if (boffset >= BITFIELD_ALIGN * 8 && size < STRUCT_ALIGN)
  522.         size = STRUCT_ALIGN;
  523.         if (boffset < BITFIELD_ALIGN * 8 && size < INT_SIZE)
  524.         size = INT_SIZE;
  525.     }
  526.     }
  527.     size = Align(size, align);
  528.     t->Size = size;
  529.     t->Align= align;
  530.  
  531.     /* We need to propagate the information to all the other copies of this type */
  532.     for (type = t->PList; type; type = type->Next)
  533.     {
  534.         if (type->Size) continue;
  535.         if (type->Id != t->Id) continue;
  536.         if (type->SubType != t->SubType) continue;
  537.         type->Align = t->Align;
  538.         type->Size  = t->Size;
  539.         type->Args  = t->Args;
  540.         type->Vars  = t->Vars;
  541.     }
  542. }
  543.  
  544. /*
  545.  *  bitfields
  546.  */
  547.  
  548. Type *
  549. MakeBitfieldType(flags, bits)
  550. long flags;
  551. int bits;
  552. {
  553.     Type **pt = ((flags & TF_UNSIGNED) ? UBitfieldType : SBitfieldType) + bits;
  554.     Type *t;
  555.  
  556.     if (*pt == NULL) {
  557.     *pt = t = AllocStructure(Type);
  558.     t->Id = TID_BITFIELD;
  559.     t->Flags = flags & TF_UNSIGNED;
  560.     t->Size = bits;         /*  only type whos size is in bits */
  561.     t->Align= BITFIELD_ALIGN;
  562.     }
  563.     return(*pt);
  564. }
  565.  
  566. /*
  567.  *  ENUMERATIONS
  568.  */
  569.  
  570. Type *
  571. FindEnumType(name)
  572. Symbol *name;
  573. {
  574.     return(&LongType);
  575. }
  576.  
  577. Type *
  578. MakeEnumType(name)
  579. Symbol *name;
  580. {
  581.     return(&LongType);
  582. }
  583.  
  584. void
  585. AddEnumIdent(type, sym, value)
  586. Type *type;
  587. Symbol *sym;
  588. long value;
  589. {
  590.     SemanticAdd(sym, TokEnumConst, (void *)value);
  591. }
  592.  
  593. Type *
  594. ActualReturnType(stmt, proctype, type)
  595. Stmt *stmt;
  596. Type *proctype;
  597. Type *type;
  598. {
  599.     dbprintf(("proctype args=%d flags=%08lx\n", proctype->Args, proctype->Flags));
  600.  
  601.     switch(type->Id) {
  602.     case TID_INT:
  603.     if (type->Size == 0)
  604.         return(&VoidType);
  605.     if (type->Size != 4)
  606.         return(&LongType);
  607.     case TID_PTR:
  608.     return(type);
  609.     case TID_FLT:
  610.     return(type);
  611.     /*
  612.     if ((proctype->Flags & TF_PROTOTYPE) || type != &FloatType)
  613.         return(type);
  614.     return(&DoubleType);
  615.     */
  616.     case TID_STRUCT:
  617.     case TID_UNION:
  618.     return(type);
  619.     case TID_ARY:
  620.     case TID_PROC:
  621.     yerror(stmt->st_LexIdx, EERROR_UNSUPPORTED_RETURN_TYPE);
  622.     return(type);
  623.     }
  624.     dbprintf(("ActualReturnType: unknown type id %d\n", type->Id));
  625.     Assert(0);
  626.     return(0);    /* not reached */
  627. }
  628.  
  629. /*
  630.  *  Returns actual type of arg being passed.  GenCall() always pushes
  631.  *  longs, but this determines what kind of extending is required.
  632.  *
  633.  *  note:   isn't careful about qualifiers
  634.  */
  635.  
  636. Type *
  637. ActualPassType(proctype, type, afterEnd)
  638. Type *proctype;
  639. Type *type;
  640. int afterEnd;
  641. {
  642.     switch(type->Id) {
  643.     case TID_BITFIELD:
  644.     type = &LongType;
  645.     break;
  646.     case TID_INT:    /*  automatically cast to long by GenCall   */
  647.     if (afterEnd && type->Size != INT_SIZE) {
  648.         type = &LongType;
  649.         break;
  650.     }
  651.     case TID_PTR:
  652.     break;
  653.     case TID_FLT:
  654.     if (afterEnd && type == &FloatType)
  655.         return(&DoubleType);
  656.     if ((proctype->Flags & TF_PROTOTYPE) || type != &FloatType)
  657.         return(type);
  658.     return(&DoubleType);
  659.     case TID_ARY:
  660.     return(TypeToPtrType(type->SubType));
  661.     case TID_PROC:
  662.     case TID_STRUCT:
  663.     case TID_UNION:
  664.     break;
  665.     default:
  666.         dbprintf(("ActualPassType: unknown type id %d\n", type->Id));
  667.         Assert(0);
  668.     break;
  669.     }
  670.     return(type);
  671. }
  672.  
  673. /*
  674.  *  Only called for non-prototyped (old style) type declarations.
  675.  *  Integer types are already properly handled, we do NOT force integer
  676.  *  arguments declared as shorts or chars to be accessed as longs!
  677.  *
  678.  *  However, floating point is a different story.  An old style fp argument
  679.  *  declared as float is actually a double and unless we convert it to a
  680.  *  float on every access (and convert assignments to doubles on every
  681.  *  assign) we must silently change the float to a double type.
  682.  */
  683.  
  684. Type *
  685. ActualArgType(type)
  686. Type *type;
  687. {
  688.     if (type->Id == TID_FLT) {
  689.     if (type == &FloatType)
  690.         type = &DoubleType;
  691.     }
  692.     return(type);
  693. }
  694.  
  695. /*
  696.  *  Returns whether two pointers are the same type or either one is
  697.  *  a (void *) (pointer to anything).  If they do not match, it issues an
  698.  *  error message indicating why.
  699.  */
  700.  
  701. void CheckPointerType(olexIdx, lexIdx, t1, t2)
  702. long olexIdx;
  703. long lexIdx;
  704. Type *t1;
  705. Type *t2;
  706. {
  707.     if (t1 == t2 ||
  708.         t1 == &VoidPtrType ||
  709.         t2 == &VoidPtrType)
  710.     return;
  711.  
  712.     /* Well, they don't strictly match.  See if we just happened to have */
  713.     /* a simple type that has a difference of opinion about const.  You  */
  714.     /* can assign a non-const pointer to a const pointer                 */
  715.  
  716.     if (t1->Size == t2->Size)
  717. /*        && (((t1->Flags ^ t2->Flags) & ~TF_COMPAREQUALS) == 0)) */
  718.     {
  719.         /* Well, we have a good chance of them being the same.  See if we */
  720.         /* have a subtype that also is compatible.                        */
  721.         if (t1->SubType && t2->SubType)
  722.         {
  723.             if (t1->SubType->Id == TID_PROC)
  724.                CompareTypes(olexIdx, lexIdx, t1->SubType, t2->SubType);
  725.             else
  726.             {
  727.                if (t1->SubType->Size != 0 && t2->SubType->Size != 0)
  728.                    CheckPointerType(olexIdx, lexIdx, t1->SubType, t2->SubType);
  729.             }
  730.             return;
  731.         }
  732.         if ((t1->SubType == NULL) && (t2->SubType == NULL))
  733.             return;
  734.     }
  735.  
  736.     /* Arrays and pointers are equivalent */
  737.     if (t1->Id == TID_PTR && t2->Id == TID_ARY) return;
  738.     if (t1->Id == TID_ARY && t2->Id == TID_PTR) return;
  739.  
  740.     yerror(lexIdx,  EWARN_PTR_PTR_MISMATCH, TypeToProtoStr(t1, 0));
  741.     yerror(olexIdx, EWARN_DOES_NOT_MATCH,   TypeToProtoStr(t2, 0));
  742. }
  743.  
  744. void
  745. GenerateRegSpecOutput(var)
  746. Var *var;
  747. {
  748.     char ano[16];
  749.     short i;
  750.  
  751.     Assert(var->Sym);
  752.  
  753.     if (RegSpecOutputOpt == 1) {
  754.     char prgno[16];
  755.     void *pragma_call = TestPragmaCall(var, prgno);
  756.  
  757.     if (pragma_call || (var->Flags & TF_REGCALL)) {
  758.         printf("##regspec @%s(", SymToString(var->Sym));
  759.  
  760.         RegCallOrder(var->Type, ano, ((pragma_call) ? prgno : NULL));
  761.         for (i = 0; i < 16 && ano[i] >= 0; ++i) {
  762.         if (i)
  763.             printf(",");
  764.         if (ano[i] < RB_ADDR)
  765.             printf("D%d", ano[i]);
  766.         else
  767.             printf("A%d", ano[i] - RB_ADDR);
  768.         }
  769.         puts(")");
  770.     } else {
  771.         printf("##regspec _%s(*)\n", SymToString(var->Sym));
  772.     }
  773.     } else {
  774.     short i;
  775.  
  776.     printf("##typespec (%s)(%s)", SymToString(var->Sym), TypeToProtoStr(var->Type->SubType, 0));
  777.     for (i = 0; i < var->Type->Args; ++i)
  778.         printf("(%s)", TypeToProtoStr(var->Type->Vars[i]->Type, 0));
  779.     puts("");
  780.     }
  781. }
  782.  
  783. /*
  784.  * Outputs a message indicating an invalid type
  785.  */
  786. void Undefined_Tag(type, sym, lexIdx)
  787. Type *type;
  788. Symbol *sym;
  789. long lexIdx;
  790. {
  791.     if (sym == NULL)
  792.     sym = FindStructUnionTag(type);
  793.  
  794.     yerror(lexIdx, EERROR_UNDEFINED_TAG, SymToString(sym));
  795. }
  796.